package cn.js189.common.util.helper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 时间与日期工具
 * 
 * @author hjw
 */
public final class DateHelper {
	private DateHelper(){}

	private static final Logger LOGGER = LoggerFactory.getLogger(DateHelper.class);
	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
	public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
	public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DEFAULT_DATETIME_FORMAT_A = "yyyyMMddHHmmss";
	public static final String DEFAULT_DATETIME_FORMAT_B = "yyyyMM";
	public static final String DEFAULT_DATETIME_FORMAT_C = "HH:mm:ss";
	public static final String DEFAULT_DATETIME_FORMAT_D = "yyyy-MM-dd";

	public static final Locale DEFAULT_LOCALE = Locale.CHINA;

	public static final String NEW_DATE_FORMAT = "yyyyMMdd";
	
	public static String changeDateFormate(String newDateStr,String oriDateFormat,String newDateFormat){
	    SimpleDateFormat oriSDF = new SimpleDateFormat(oriDateFormat);
	    SimpleDateFormat newSDF = new SimpleDateFormat(newDateFormat);
	    try {
            return newSDF.format(oriSDF.parse(newDateStr));
        } catch (ParseException e) {
		    LOGGER.debug(e.getMessage());
	    }
	    return "";
	}

	public static String getCurrentTimeStampString(){
		return DateHelper.formatDateTime(new Date(), "yyyyMMddHHmmssSSS", Locale.CHINA);
	}

	public static String getDefaultDateFormat() {
		return DEFAULT_DATE_FORMAT;
	}


	public static String getDefaultTimeFormat() {
		return DEFAULT_TIME_FORMAT;
	}


	public static String getDefaultDateTimeFormat() {
		return DEFAULT_DATE_TIME_FORMAT;
	}

	public static Locale getDefaultLocal() {
		return DEFAULT_LOCALE;
	}

	public static Date getCurrent() {
		return new Date(System.currentTimeMillis());
	}


	/**
	 * 格式化日期时间
	 * 
	 * @param calendar
	 *            时间
	 * @param format
	 *            格式
	 * @param locale
	 *            地域
	 * @return
	 */
	public static String formatDateTime(Calendar calendar, String format,
			Locale locale) {
		SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
		return sdf.format(calendar.getTime());
	}

	/**
	 * 格式化日期时间
	 * 
	 * @param date
	 *            时间
	 * @param format
	 *            格式
	 * @param locale
	 *            地域
	 * @return
	 */
	public static String formatDateTime(Date date, String format, Locale locale) {
		SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
		return sdf.format(date);
	}

	/**
	 * 取当前服务器上的日期。使用默认日期格式。<br />
	 * 在没有改变的情况下.默认格式为"yyyy-MM-dd".
	 * 
	 * @return
	 */
	public static String getCurrentDate() {
		return formatDateTime(getCurrent(), getDefaultDateFormat(),
				getDefaultLocal());
	}

	/**
	 * 取当前服务器上的时间.使用默认时间格式.<br />
	 * 在没有改变的情况下.默认格式为"HH:mm:ss".
	 * 
	 * @return
	 */
	public static String getCurrentTime() {
		return formatDateTime(getCurrent(), getDefaultTimeFormat(),
				getDefaultLocal());
	}

	/**
	 * 取当前服务器上的日期时间.使用默认日期时间格式.<br />
	 * 在没有改变的情况下.默认格式为"yyyy-MM-dd HH:mm:ss".
	 * 
	 * @return
	 */
	public static String getCurrentDateTime() {
		return formatDateTime(getCurrent(), getDefaultDateTimeFormat(),
				getDefaultLocal());
	}
	
	public static String getCurrentDateTimeWithFormat(String format) {
        return formatDateTime(getCurrent(), format,
                getDefaultLocal());
    }

	/**
	 * 转换Date为Timestamp.
	 * 
	 * @param date
	 * @return
	 */
	public static Timestamp getTimestamp(Date date) {
		return new Timestamp(date.getTime());
	}

	/**
	 * 转换Timestamp为Date.
	 * 
	 * @param timestamp
	 * @return
	 */
	public static Date getDate(Timestamp timestamp) {
		return new Date(timestamp.getTime());
	}

	/**
	 * 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数
	 * 
	 * @param date
	 * @return
	 */
	public static long getTime(Date date) {
		return date.getTime();
	}

	/**
	 * 使用指定的格式和地域解析字段串为时间
	 * 
	 * @param format
	 *            格式
	 * @param locale
	 *            地域
	 * @param str
	 *            字段串
	 * @return
	 */
	public static Date parseDateTime(String format, Locale locale, String str) {
		SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
		try {
			return sdf.parse(str);
		} catch (ParseException e) {
			LOGGER.debug(e.getMessage());
			return null;
		}
	}

	/**
	 * 使用默认值解析表示日期时间的字符
	 * 
	 * @param str
	 * @return
	 */
	public static Date parseDateTime(String str) {
		return parseDateTime(getDefaultDateTimeFormat(), getDefaultLocal(), str);
	}

	/**
	 * 使用默认值解析表示日期的字符
	 * 
	 * @param str
	 * @return
	 */
	public static Date parseDate(String str) {
		return parseDateTime(getDefaultDateFormat(), getDefaultLocal(), str);
	}

	/**
	 * 使用默认值解析表示时间的字符
	 * 
	 * @param str
	 * @return
	 */
	public static Date parseTime(String str) {
		return parseDateTime(getDefaultTimeFormat(), getDefaultLocal(), str);
	}
	
	/**
	 * 开始时间等于月初，结束时间等于月末
	 * @param begDate
	 * @param endDate
	 * @return true是  false否
	 */
	public static boolean isAllMonthFlag(String begDate,String endDate){
		Date date = parseDateTime(NEW_DATE_FORMAT, getDefaultLocal(), begDate);
		String getMonthStartDate = getMonthStart(date, NEW_DATE_FORMAT);
		String getMonthEndDate = getMonthEnd(date, NEW_DATE_FORMAT);
		return (getMonthStartDate.equals(begDate) && getMonthEndDate.equals(endDate));
	}

	/**
	 * 使用指定格式取指定时间的月首
	 * 
	 * @param format
	 * @return
	 */
	public static String getMonthStart(Date date, String format) {
		Calendar localTime = Calendar.getInstance(getDefaultLocal());
		localTime.setTime(date);
		localTime.set(Calendar.DAY_OF_MONTH, 1);
		return formatDateTime(localTime, format, getDefaultLocal());
	}

	/**
	 * 使用指定格式取指定时间的月末
	 * 
	 * @return
	 */
	public static String getMonthEnd(Date date, String format) {
		Calendar localTime = Calendar.getInstance(getDefaultLocal());
		localTime.setTime(date);
		localTime.add(Calendar.MONTH, 1);
		localTime.set(Calendar.DAY_OF_MONTH, 1);
		localTime.add(Calendar.DAY_OF_MONTH, -1);
		return formatDateTime(localTime, format, getDefaultLocal());
	}

	/**
	 * 对指定时间进行增减操作后返回指定格式的时间串
	 * 
	 * @param date
	 *            指定的时间
	 * @param calendarField
	 *            在{@link Calendar}类定义的字段
	 * @param amount
	 *            增加数量
	 * @param format
	 *            指定格式
	 * @return
	 */
	public static String addDateTime(Date date, int calendarField, int amount,
			String format) {
		Calendar localTime = Calendar.getInstance(getDefaultLocal());
		localTime.setTime(date);
		localTime.add(calendarField, amount);
		return formatDateTime(localTime, format, getDefaultLocal());
	}

	/**
	 * 比较两个时间的顺序
	 * 
	 * @param src
	 * @param dst
	 * @return 如果src在dst之前则 小于0<br />
	 *         如果src在dst之后则 大于0<br />
	 *         如果相同则 等于0
	 */
	public static int comparaDateTime(Date src, Date dst) {
		return src.compareTo(dst);
	}
	
	/**
	 * 将日期的时分秒部分去掉
	 * @param date
	 * @return
	 */
	public static Date truncateTime(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		
		return cal.getTime();
	}
	
	/**
	 * 将java.util.Date转换成java.sql.Date
	 * @param date
	 * @return
	 */
	public static java.sql.Date transfer2SqlDate(Date date){
		return new java.sql.Date(date.getTime());
	}
	
	/**
	 * java.util.Date转成java.sql.Timestamp
	 * @param date
	 * @return
	 */
	public static Timestamp transfer2Timestamp(Date date){
		return new Timestamp(date.getTime());
	}
	
	public static Date addDate(Date date, int dateField, int num){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(dateField, num);
		
		return cal.getTime();
	}
	
	public static Date getLastDateOfMonth(Date date){
		Date truncdate = truncateTime(date);
		Calendar cal = Calendar.getInstance();
		cal.setTime(truncdate);
		int maxday = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		
		cal.set(Calendar.DAY_OF_MONTH, maxday);
		return cal.getTime();
	}

	/**
	 * 传入2个日期字符串,返回日期较早的字符串
	 * @param dateStr1 第一个日期字符串 格式yyyy-MM-dd HH:mm:ss
	 * @param dateStr2 第二个日期字符串 格式yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getEarlyDateString(String dateStr1,String dateStr2){

		if(StringUtils.isEmpty(dateStr1) || StringUtils.isEmpty(dateStr2)){
			return null;
		}

		SimpleDateFormat sdf = new SimpleDateFormat(DateHelper.DEFAULT_DATE_TIME_FORMAT);
		try {
			Date date1 = sdf.parse(dateStr1);
			Date date2 = sdf.parse(dateStr2);

			int result = date1.compareTo(date2);
			return result <= 0 ? dateStr1 : dateStr2;

		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 通过时间秒毫秒数判断两个时间的间隔(天)
	 *
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	public static int differentDaysByMillisecond(Date beginDate, Date endDate) {
		return (int) ((endDate.getTime() - beginDate.getTime()) / (1000 * 3600 * 24));
	}

    /**
     * 通过时间秒毫秒数判断两个时间的间隔(分钟)
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static int differentMinutesByMillisecond(Date beginDate, Date endDate) {
        return (int) ((endDate.getTime() - beginDate.getTime()) / (1000 * 60));
    }

	/**
	 * 判断当前日期是否在失效期内
	 * @param expDateStr 失效时间
	 * @return currentDate < expDate = true
	 */
	public static boolean compareDate(String expDateStr) {
		if (StringUtils.isEmpty(expDateStr)) {
			return false;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(DateHelper.DEFAULT_DATE_TIME_FORMAT);
		Date expDate = null;
		try {
			expDate = sdf.parse(expDateStr);
		} catch (ParseException e) {
			return false;
		}
		Date currentDate = new Date();
		int result = currentDate.compareTo(expDate);

		return result < 0;

	}
	/**
	 * 获取一个时间中最大的日期
	 * Description: <br> 
	 *  
	 * @author yangyang<br>
	 * 2019年4月12日
	 * @param date
	 * @return int<br>
	 */
	public static int getTotalDaysOfMonth(Date date){
	    Calendar ca = Calendar.getInstance();
	    ca.setTime(date);
	    return ca.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

//	public static Pair<String, String> getDate(int monthOffSet){
//		Calendar cale = Calendar.getInstance();
//		int eMonth = cale.get(Calendar.MONTH) + 1;
//		String strEMonth = eMonth < 10 ? "0" + eMonth : eMonth + "";
//		String eDate = cale.get(Calendar.YEAR) + "" + strEMonth + (cale.getActualMaximum(Calendar.DAY_OF_MONTH)) + "235959";
//
//		cale.add(Calendar.MONTH, monthOffSet);
//		int sMonth = cale.get(Calendar.MONTH) + 1;
//		String strSMonth = sMonth < 10 ? "0" + sMonth : sMonth + "";
//		String sDate = cale.get(Calendar.YEAR) + "" + strSMonth + "01000000";
//
//		return new Pair<>(sDate, eDate);
//	}

	public static Date formatToUTC(String dateString) {
		if (StringUtils.isEmpty(dateString)) {
			return null;
		}
		try {
			dateString = dateString.replace("Z", " UTC");
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
			return format.parse(dateString);
		} catch (Exception e) {
			return null;
		}
	}

	//查询企信分割6个月
	public static String extendedTime(String timeStr) {

		Date currDate =DateHelper.parseDateTime(DateHelper.DEFAULT_DATETIME_FORMAT_A,DateHelper.DEFAULT_LOCALE,timeStr);
		Calendar ca = Calendar.getInstance();
		int currYear = ca.get(Calendar.YEAR);//获取当前年份
		int currMonth = ca.get(Calendar.MONTH);//获取当前月份

		ca.setTime(currDate);
		ca.add(Calendar.MONTH, 6);
		currDate = ca.getTime();
		int endYear = ca.get(Calendar.YEAR);//获取年份
		int endMonth = ca.get(Calendar.MONTH);//获取月份

		//时间在当前时间之前则展示分割时间，之后则返回空
		String endDate = "";
		if((currYear == endYear && currMonth>endMonth)||(currYear>endYear)){
			endDate = DateHelper.formatDateTime(currDate, DateHelper.DEFAULT_DATETIME_FORMAT_A, DateHelper.DEFAULT_LOCALE);
		}

		return endDate;
	}
}
